/**************************************************************************
	FSHOME - Curtains Handle Node - Bridge eth-485
***************************************************************************/
#include "bconf/DINo_v2_PeerBridge_RS485.h"
#include "fshSoulissCommon.h"

/*
#define SKETCH_DEBUG
#define VNET_DEBUG_INSKETCH
#define VNET_DEBUG    1
// #define MaCaco_DEBUG_INSKETCH
// #define MaCaco_DEBUG  1
// temporary: to be defined by Dario
#define USART_DEBUG  1
#define DINOv2_USART_DEBUG  1
*/

#include "Souliss.h"
#include "SpeakEasy.h"
#include <SPI.h>

// Include common definitions
#include "DINo_v2_HW_Setup.h"			// standard board hw configuration
#include "fshSoulissNetwork.h"			// standard board hw configuration

// DS18B20 support
#include <OneWire.h>
#include <DallasTemperature.h>

// SLOT definitions
#define CURTAIN_1_SLOT		0
#define CURTAIN_2_SLOT		1
#define TEMPERATURE_SLOT	2	//Temperature is a half float it will use 2 slots

// Global Variables

// Network address
uint8_t ip_address[4]  = {IP_ADDRESS_1, IP_ADDRESS_2, IP_ADDRESS_3, IP_ADDRESS_R2B1};
uint8_t subnet_mask[4] = {255, 255, 255, 0};
uint8_t ip_gateway[4]  = {IP_ADDRESS_1, IP_ADDRESS_2, IP_ADDRESS_3, IP_ADDRESS_4_NETGW};

bool ds18b20_RequestPhase = true;

// Setup oneWire instance to handle the DS18B20 sensor
OneWire oneWire(DINOII_1WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup()
{
	#ifdef SKETCH_DEBUG
	Serial.begin(9600);
	#endif

	// Init the board
	DINo_v2_HW_Setup();
	
	// Setup network configuration
	Souliss_SetIPAddress(ip_address, subnet_mask, ip_gateway);
	Souliss_SetAddress(RS485_ADDRESS_R2B1, SOULISS_SUBNET_MASK, SOULISS_SUPERNODE);         

	// Set Up the slots
	Souliss_SetT22(memory_map, CURTAIN_1_SLOT);
	Souliss_SetT22(memory_map, CURTAIN_2_SLOT);
	Set_Temperature(TEMPERATURE_SLOT);

	// Start up the DallasTemperature library
	sensors.setWaitForConversion(false);
	sensors.setResolution(12);
	sensors.begin();
} 

void loop()
{ 
	EXECUTEFAST() {						
		UPDATEFAST();	
		
		FAST_50ms() {
		
			// Use OPEN and CLOSE Commands
			Souliss_DigIn(IN1, Souliss_T2n_OpenCmd, memory_map, CURTAIN_1_SLOT);
			Souliss_DigIn(IN2, Souliss_T2n_CloseCmd, memory_map, CURTAIN_1_SLOT);
			Souliss_DigIn(IN3, Souliss_T2n_OpenCmd, memory_map, CURTAIN_2_SLOT);
			Souliss_DigIn(IN4, Souliss_T2n_CloseCmd, memory_map, CURTAIN_2_SLOT);
		
			// Run the logic
			Souliss_Logic_T22(memory_map, CURTAIN_1_SLOT, &data_changed);
			Souliss_Logic_T22(memory_map, CURTAIN_2_SLOT, &data_changed);
			
			// Act on outputs, the Stop command is defined as Open | Close and
			// active both the outputs
			Souliss_DigOut(OUT1, Souliss_T2n_Coil_Open, memory_map, CURTAIN_1_SLOT);	
			Souliss_DigOut(OUT2, Souliss_T2n_Coil_Close, memory_map, CURTAIN_1_SLOT);	
			Souliss_DigOut(OUT3, Souliss_T2n_Coil_Open, memory_map, CURTAIN_2_SLOT);	
			Souliss_DigOut(OUT4, Souliss_T2n_Coil_Close, memory_map, CURTAIN_2_SLOT);	
		} 
		
		// Here we process all communication with other nodes
		FAST_PeerComms();
		
		// At first runs, we look for a gateway to join
		START_PeerJoin();
		
		// Periodically check if the peer node has joined the gateway
		FAST_1110ms() {
			if(JoinInProgress())	// If join is in progress, toogle the LED at every turn
				ToogleLED();
			else
				TurnOnLED();		// Once completed, turn ON
		}		
		
	}
	
	EXECUTESLOW() {	
		UPDATESLOW();

		// Here we periodically check for a gateway to join
		SLOW_PeerJoin();		

		SLOW_10s() {
			Timer_Windows(CURTAIN_1_SLOT);
			Timer_Windows(CURTAIN_2_SLOT);	
		} 	  

		SLOW_50s() { 
			TurnOffLED();
			if(ds18b20_RequestPhase) {
			  sensors.requestTemperatures(); // Send the command to get temperatures
			}
			else {
				float temperature;
				temperature = sensors.getTempCByIndex(0);	
				// Read temperature value from DHT sensor and convert from single-precision to half-precision
				Souliss_ImportAnalog(memory_map, TEMPERATURE_SLOT, &temperature);
				// Logic_Temperature(TEMPERATURE_SLOT);
				Souliss_Logic_T52(memory_map, TEMPERATURE_SLOT, 0, &data_changed);
			} 	  
			ds18b20_RequestPhase = !ds18b20_RequestPhase;
			TurnOnLED();
		} 	  
	}
} 
